home *** CD-ROM | disk | FTP | other *** search
- From: ihnp4!think!massar (JP Massar)
- Subject: rolodex database program -- part 2 of 3
- Newsgroups: mod.sources
- Approved: jpn@panda.UUCP
-
- Mod.sources: Volume 4, Issue 28
- Submitted by: ihnp4!think!massar (JP Massar)
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # choices.h
- # clear.c
- # datadef.h
- # io.c
- # menuaux.c
- # operations.c
- # options.c
- # rlist.c
- # rolo.c
- # rolodefs.h
- # rolofiles.h
- # search.c
- # update.c
- # This archive created: Thu Mar 13 18:29:52 1986
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'choices.h'" '(685 characters)'
- if test -f 'choices.h'
- then
- echo shar: will not over-write existing file "'choices.h'"
- else
- cat << \SHAR_EOF > 'choices.h'
- typedef enum { P_CONTINUE, P_NEXT_PERSON, P_ABORT, P_HELP } P_Choices;
-
- typedef enum {
-
- M_SEARCH_BY_OTHER, M_SEARCH_BY_NAME, M_PRINT_TO_LASER_PRINTER,
- M_HELP, M_EXIT, M_PERUSE, M_SAVE, M_ADD
-
- } Main_Choices;
-
- typedef enum {
-
- A_ABORT_ADD, A_BACKUP, A_FILL_IN_REST,
- A_ABORT_ROLO, A_HELP, A_NO_DATA
-
- } Add_Choices;
-
- typedef enum {
-
- E_ABORT, E_UPDATE, E_DELETE, E_CONTINUE, E_PREV, E_HELP, E_SCAN
-
- } E_Choices;
-
- typedef enum { U_ABORT, U_HELP, U_END_UPDATE } U_Choices;
-
- typedef enum { S_ABORT, S_HELP, S_SCAN_ONE_BY_ONE } S_Choices;
-
- typedef enum { O_ABORT, O_HELP, O_BACKUP, O_DONE_OTHERS } O_Choices;
- SHAR_EOF
- if test 685 -ne "`wc -c < 'choices.h'`"
- then
- echo shar: error transmitting "'choices.h'" '(should have been 685 characters)'
- fi
- fi
- echo shar: extracting "'clear.c'" '(930 characters)'
- if test -f 'clear.c'
- then
- echo shar: will not over-write existing file "'clear.c'"
- else
- cat << \SHAR_EOF > 'clear.c'
- #include <stdio.h>
- #ifdef TERMINFO
- #include <term.h>
- #endif
- #undef putchar
-
- int putchar();
- static int ok_to_clear;
-
- #ifdef TERMCAP
- static char clear_screen[128] = 0;
- static int lines;
- #endif
-
- clearinit ()
- {
- #ifdef TERMINFO
- int i;
- setupterm(getenv("TERM"),1,&i);
- ok_to_clear = (i == 1) ? 1 : 0;
- if (i != 1) {
- fprintf(stderr,"Warning: Terminal type unknown\n");
- }
- return (i == 1) ? 0 : -1;
- #endif
- #ifdef TERMCAP
- char tc[1024];
- char *ptr = clear_screen;
-
- if (tgetent(tc, getenv("TERM")) < 1) {
- ok_to_clear = 0;
- return;
- }
- tgetstr("cl", &ptr);
- lines = tgetnum("li");
- ok_to_clear = (clear_screen[0] != 0 && lines > 0);
-
- #endif
- }
-
- clear_the_screen ()
- {
- #ifdef TERMINFO
- if (!ok_to_clear) return;
- tputs(clear_screen,lines,putchar);
- fflush(stdout);
- #endif
- #ifdef TERMCAP
- if (!ok_to_clear) return;
- tputs(clear_screen,lines,putchar);
- fflush(stdout);
- #endif
- }
- SHAR_EOF
- if test 930 -ne "`wc -c < 'clear.c'`"
- then
- echo shar: error transmitting "'clear.c'" '(should have been 930 characters)'
- fi
- fi
- echo shar: extracting "'datadef.h'" '(1911 characters)'
- if test -f 'datadef.h'
- then
- echo shar: will not over-write existing file "'datadef.h'"
- else
- cat << \SHAR_EOF > 'datadef.h'
- #define ABORTSTRING "\\"
- #define ABORTCHAR '\\'
-
- #define MAXMATCHES 17
-
- #define N_BASIC_FIELDS 8
- #define OTHER -1
-
- typedef enum Basic_Field {
-
- R_NAME = 0, R_WORK_PHONE, R_HOME_PHONE, R_COMPANY, R_WORK_ADDRESS,
- R_HOME_ADDRESS, R_REMARKS, R_UPDATED
-
- };
-
- extern char *Field_Names[];
-
- /* A Rolodex entry */
-
- typedef struct {
-
- char *basicfields[N_BASIC_FIELDS];
- int n_others;
- char **other_fields;
-
- } Rolo_Entry, *Ptr_Rolo_Entry;
-
-
- #define get_basic_rolo_field(n,x) (((x) -> basicfields)[(n)])
- #define get_n_others(x) ((x) -> n_others)
- #define get_other_field(n,x) (((x) -> other_fields)[n])
-
- #define set_basic_rolo_field(n,x,s) (((x) -> basicfields[(n)]) = (s))
- #define set_n_others(x,n) (((x) -> n_others) = (n))
- #define incr_n_others(x) (((x) -> n_others)++)
- #define set_other_field(n,x,s) ((((x) -> other_fields)[n]) = (s))
-
- typedef struct link {
-
- Ptr_Rolo_Entry entry;
- int matched;
- struct link *prev;
- struct link *next;
-
- } Rolo_List, *Ptr_Rolo_List;
-
-
- #define get_next_link(x) ((x) -> next)
- #define get_prev_link(x) ((x) -> prev)
- #define get_entry(x) ((x) -> entry)
- #define get_matched(x) ((x) -> matched)
-
- #define set_next_link(x,y) (((x) -> next) = (y))
- #define set_prev_link(x,y) (((x) -> prev) = (y))
- #define set_entry(x,y) (((x) -> entry) = (y))
- #define set_matched(x) (((x) -> matched) = 1)
- #define unset_matched(x) (((x) -> matched) = 0);
-
- extern Ptr_Rolo_List Begin_Rlist;
- extern Ptr_Rolo_List End_Rlist;
-
- #define MAXLINELEN 80
- #define DIRPATHLEN 100
-
- extern int changed;
- extern int reorder_file;
- extern int rololocked;
-
- extern char *rolo_emalloc();
- extern char *malloc();
- extern Ptr_Rolo_List new_link_with_entry();
- extern char *copystr();
- extern int compare_links();
- extern char *timestring();
- extern char *homedir(), *libdir();
- extern char *getenv();
- extern char *ctime();
- extern char *select_search_string();
- extern int in_search_mode;
- SHAR_EOF
- if test 1911 -ne "`wc -c < 'datadef.h'`"
- then
- echo shar: error transmitting "'datadef.h'" '(should have been 1911 characters)'
- fi
- fi
- echo shar: extracting "'io.c'" '(8455 characters)'
- if test -f 'io.c'
- then
- echo shar: will not over-write existing file "'io.c'"
- else
- cat << \SHAR_EOF > 'io.c'
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/file.h>
- #include <ctype.h>
-
- #include "sys5.h"
-
- #ifdef TMC
- #include <ctools.h>
- #else
- #include "ctools.h"
- #endif
-
- #include "datadef.h"
- #include "rolofiles.h"
-
-
- char *Field_Names[N_BASIC_FIELDS] = {
-
- "Name: ", "Work Phone: ", "Home Phone: ", "Company: ",
- "Work Address: ", "Home Address: ", "Remarks: ", "Date Updated: "
-
- };
-
- Ptr_Rolo_List Begin_Rlist = 0;
- Ptr_Rolo_List End_Rlist = 0;
- Ptr_Rolo_List Current_Entry = 0;
-
- static char *rolofiledata;
-
- read_rolodex (fd) int fd;
-
- {
- struct stat statdata;
- int filesize,i,j,k,start_of_others,warning_given;
- Ptr_Rolo_Entry newentry,oldentry,currententry;
- Ptr_Rolo_List newlink,rptr;
- char *next_field,*next_other,*oldname,*currentname;
- char **other_pointers;
- int n_entries = 0;
-
- /* find out how many bytes are in the file */
-
- fstat(fd,&statdata);
- if ((filesize = statdata.st_size) == 0) {
- return(0);
- }
-
- /* create an array of characters that big */
-
- rolofiledata = rolo_emalloc(filesize);
-
- /* read them all in at once for efficiency */
-
- if (filesize != read(fd,rolofiledata,filesize)) {
- fprintf(stderr,"rolodex read failed\n");
- exit(-1);
- }
-
- j = 0;
-
- /* for each entry in the rolodex file */
-
- while (j < filesize) {
-
- n_entries++;
-
- /* create the link and space for the data entry */
-
- newlink = new_link_with_entry();
- newentry = get_entry(newlink);
- if (j == 0) {
- Begin_Rlist = newlink;
- set_prev_link(newlink,0);
- set_next_link(newlink,0);
- }
- else {
- set_next_link(End_Rlist,newlink);
- set_prev_link(newlink,End_Rlist);
- set_next_link(newlink,0);
- }
- End_Rlist = newlink;
-
- /* locate each required field in the character array and change */
- /* the ending line feed to a null. Insert a pointer to the */
- /* beginning of the field into the data entry */
-
- for (i = 0; i < N_BASIC_FIELDS; i++) {
- next_field = rolofiledata + j;
- while (rolofiledata[j] != '\n') {
- j++;
- }
- rolofiledata[j] = '\0';
- j++;
- set_basic_rolo_field(i,newentry,next_field);
- }
-
- /* the end of an entry is indicated by two adjacent newlines */
-
- if (rolofiledata[j] == '\n') {
- j++;
- newentry -> other_fields = 0;
- continue;
- }
-
- /* there must be additional, user-inserted fields. Find out how many. */
-
- start_of_others = j;
- while (1) {
- while (rolofiledata[j] != '\n') {
- j++;
- }
- incr_n_others(newentry);
- j++;
- if (rolofiledata[j] == '\n') {
- j++;
- break;
- }
- }
-
- /* allocate an array of character pointers to hold these fields */
-
- other_pointers = (char **)rolo_emalloc(get_n_others(newentry)*sizeof(char *));
-
- /* separate each field and insert a pointer to it in the char array */
-
- k = start_of_others;
- for (i = 0; i < get_n_others(newentry); i++) {
- next_other = rolofiledata + k;
- while (rolofiledata[k] != '\n') {
- k++;
- }
- rolofiledata[k] = '\0';
- other_pointers[i] = next_other;
- k++;
- }
-
- /* insert the pointer to this character array into the data entry */
-
- newentry -> other_fields = other_pointers;
-
- }
-
- /* check that all the entries are in alphabetical order by name */
-
- warning_given = 0;
- rptr = get_next_link(Begin_Rlist);
- while (rptr != 0) {
- if (1 == compare_links(get_prev_link(rptr),rptr)) {
- if (!warning_given) fprintf(stderr,"Warning, rolodex out of order\n");
- warning_given = 1;
- reorder_file = 1;
- }
- rptr = get_next_link(rptr);
- }
-
- return(n_entries);
-
- }
-
-
- write_rolo_list (fp) FILE *fp;
-
- /* write the entire in-core rolodex to a file */
-
- {
-
- Ptr_Rolo_List rptr;
- Ptr_Rolo_Entry entry;
- int j;
-
- rptr = Begin_Rlist;
-
- while (rptr != 0) {
- entry = get_entry(rptr);
- for (j = 0; j < N_BASIC_FIELDS; j++) {
- fprintf(fp,"%s\n",get_basic_rolo_field(j,entry));
- }
- for (j = 0; j < get_n_others(entry); j++) {
- fprintf(fp,"%s\n",get_other_field(j,entry));
- }
- fprintf(fp,"\n");
- rptr = get_next_link(rptr);
- }
-
- }
-
-
- write_rolo (fp1,fp2) FILE *fp1; FILE *fp2;
-
- {
- write_rolo_list(fp1);
- write_rolo_list(fp2);
- }
-
-
- display_basic_field (name,value,show,up) char *name; char *value; int show,up;
- {
- int semi = 0;
- int i;
- if (all_whitespace(value) && !show) return;
- printf("%-25s",name);
- while (*value != '\0') {
- if (*value == ';') {
- while (*++value == ' ');
- putchar('\n');
- for (i = 0; i < (up ? 28 : 25); i++) putchar(' ');
- semi = 1;
- }
- else {
- semi = 0;
- putchar(*value++);
- }
- }
- putchar('\n');
- }
-
-
- display_other_field (fieldstring) char *fieldstring;
- {
- int already_put_sep = 0;
- int count = 0;
- int i;
- while (*fieldstring != '\0') {
- if (*fieldstring == ';' && already_put_sep) {
- while (*++fieldstring == ' ');
- putchar('\n');
- for (i = 0; i < 25; i++) putchar(' ');
- continue;
- }
- putchar(*fieldstring);
- count++;
- if (*fieldstring == ':' && !already_put_sep) {
- for (i = count; i < 24; i++) putchar(' ');
- already_put_sep = 1;
- }
- fieldstring++;
- }
- putchar('\n');
- }
-
-
- summarize_entry_list (rlist,ss) Ptr_Rolo_List rlist; char *ss;
-
- /* print out the Name field for each entry that is tagged as matched */
- /* and number each entry. */
-
- {
- int count = 1;
- clear_the_screen();
- printf("Entries that match '%s' :\n\n",ss);
- while (rlist != 0) {
- if (get_matched(rlist)) {
- printf (
- "%d. \t%s\n",
- count++,
- get_basic_rolo_field((int) R_NAME,get_entry(rlist))
- );
- }
- rlist = get_next_link(rlist);
- }
- putchar('\n');
- }
-
-
- display_field_names ()
-
- /* display and number each standard field name. */
-
- {
- int j;
- char *name;
- clear_the_screen();
- for (j = 0; j < N_BASIC_FIELDS - 1; j++) {
- name = Field_Names[j];
- printf("%d. ",j+1);
- while (*name != ':') putchar(*name++);
- putchar('\n');
- }
- printf("%d. ",N_BASIC_FIELDS);
- printf("A user created item name\n\n");
- }
-
-
- display_entry (entry) Ptr_Rolo_Entry entry;
-
- {
- int j,n_others;
- char *string;
-
- clear_the_screen();
-
- /* display the standard fields other than Date Updated */
-
- for (j = 0; j < N_BASIC_FIELDS - 1; j++) {
- string = get_basic_rolo_field(j,entry);
- display_basic_field(Field_Names[j],string,0,0);
- }
-
- /* display any additional fields the user has defined for this entry */
-
- n_others = get_n_others(entry);
- for (j = 0; j < n_others; j++) {
- string = get_other_field(j,entry);
- display_other_field(string);
- }
-
- /* display the Date Updated field */
-
- j = N_BASIC_FIELDS - 1;
- display_basic_field(Field_Names[j],get_basic_rolo_field(j,entry),0,0);
- fprintf(stdout,"\n");
-
- }
-
-
- display_entry_for_update (entry) Ptr_Rolo_Entry entry;
-
- /* same as display_entry, except each item is numbered and the Date Updated */
- /* item is not displayed */
-
- {
- int j,n_others;
- char *string;
- int count = 1;
-
- clear_the_screen();
-
- for (j = 0; j < N_BASIC_FIELDS - 1; j++) {
- string = get_basic_rolo_field(j,entry);
- printf("%d. ",count++);
- display_basic_field(Field_Names[j],string,1,1);
- }
-
- n_others = get_n_others(entry);
- for (j = 0; j < n_others; j++) {
- string = get_other_field(j,entry);
- printf("%d. ",count++);
- display_other_field(string);
- }
-
- printf("%d. Add a new user defined field\n",count);
-
- fprintf(stdout,"\n");
-
- }
-
-
- int cathelpfile (filepath,helptopic,clear)
-
- char *filepath, *helptopic;
- int clear;
-
- {
- FILE *fp;
- char buffer[MAXLINELEN];
- if (clear) clear_the_screen();
- if (NULL == (fp = fopen(filepath,"r"))) {
- if (helptopic) {
- printf("No help available on %s, sorry.\n\n",helptopic);
- }
- else {
- fprintf(stderr,"Fatal error, can't open %s\n",filepath);
- exit(-1);
- }
- return;
- }
- while (NULL != fgets(buffer,MAXLINELEN,fp)) printf("%s",buffer);
- printf("\n");
- fclose(fp);
- return;
- }
-
-
- any_char_to_continue ()
- {
- char buffer[80];
- printf("RETURN to continue: ");
- fgets(buffer,80,stdin);
- return;
- }
- SHAR_EOF
- if test 8455 -ne "`wc -c < 'io.c'`"
- then
- echo shar: error transmitting "'io.c'" '(should have been 8455 characters)'
- fi
- fi
- echo shar: extracting "'menuaux.c'" '(1433 characters)'
- if test -f 'menuaux.c'
- then
- echo shar: will not over-write existing file "'menuaux.c'"
- else
- cat << \SHAR_EOF > 'menuaux.c'
- #include <stdio.h>
- #include <ctype.h>
-
- #include "sys5.h"
-
- #ifdef TMC
- #include <ctools.h>
- #else
- #include "ctools.h"
- #endif
- #include "args.h"
- #include "menu.h"
-
- #include "rolofiles.h"
- #include "rolodefs.h"
- #include "datadef.h"
-
-
- rolo_menu_yes_no (prompt,rtn_default,help_allowed,helpfile,subject)
-
- char *prompt;
- int rtn_default;
- int help_allowed;
- char *helpfile, *subject;
-
- {
- int rval;
- reask :
- rval = menu_yes_no_abort_or_help (
- prompt,ABORTSTRING,help_allowed,rtn_default
- );
- switch (rval) {
- case MENU_EOF :
- user_eof();
- break;
- case MENU_HELP :
- cathelpfile(libdir(helpfile),subject,1);
- goto reask;
- break;
- default :
- return(rval);
- break;
- }
- }
-
-
- rolo_menu_data_help_or_abort (prompt,helpfile,subject,ptr_response)
-
- char *prompt, *helpfile, *subject;
- char **ptr_response;
-
- {
- int rval;
- reask :
- rval = menu_data_help_or_abort(prompt,ABORTSTRING,ptr_response);
- if (rval == MENU_EOF) user_eof();
- if (rval == MENU_HELP) {
- cathelpfile(libdir(helpfile),subject,1);
- goto reask;
- }
- return(rval);
- }
-
-
- rolo_menu_number_help_or_abort (prompt,low,high,ptr_ival)
-
- char *prompt;
- int low,high,*ptr_ival;
-
- {
- int rval;
- if (MENU_EOF == (rval = menu_number_help_or_abort (
- prompt,ABORTSTRING,low,high,ptr_ival
- )))
- user_eof();
- return(rval);
- }
- SHAR_EOF
- if test 1433 -ne "`wc -c < 'menuaux.c'`"
- then
- echo shar: error transmitting "'menuaux.c'" '(should have been 1433 characters)'
- fi
- fi
- echo shar: extracting "'operations.c'" '(8950 characters)'
- if test -f 'operations.c'
- then
- echo shar: will not over-write existing file "'operations.c'"
- else
- cat << \SHAR_EOF > 'operations.c'
- #include <stdio.h>
- #include <ctype.h>
-
- #include "sys5.h"
-
- #ifdef TMC
- #include <ctools.h>
- #else
- #include "ctools.h"
- #endif
- #include "args.h"
- #include "menu.h"
- #include "mem.h"
-
-
- #include "rolofiles.h"
- #include "rolodefs.h"
- #include "datadef.h"
- #include "choices.h"
-
- extern char *ctime();
-
- Ptr_Rolo_List create_entry (basicdata,otherdata) char **basicdata, **otherdata;
- {
- Ptr_Rolo_List newlink;
- Ptr_Rolo_Entry newentry;
- int i,j;
- newlink = new_link_with_entry();
- newentry = get_entry(newlink);
- for (j = 0; j < N_BASIC_FIELDS; j++) {
- set_basic_rolo_field(j,newentry,basicdata[j]);
- }
- j = 0;
- while (otherdata[j] != 0) j++;
- set_n_others(newentry,j);
- if (j > 0) {
- newentry -> other_fields = (char **) rolo_emalloc(j*sizeof(char *));
- for (i = 0; i < j; i++) {
- set_other_field(i,newentry,otherdata[i]);
- }
- }
- else newentry -> other_fields = 0;
- return(newlink);
- }
-
-
- other_fields ()
- {
- int rval;
- rval = rolo_menu_yes_no (
- "Additional fields? ",DEFAULT_NO,1,
- "morefieldshelp","additional fields"
- );
- return(rval == MENU_YES);
- }
-
-
- add_the_entry ()
- {
- return(MENU_YES == rolo_menu_yes_no (
- "Add new entry to rolodex? ",DEFAULT_YES,1,
- "newaddhelp","adding newly entered entry"
- ));
- }
-
-
- rolo_add ()
-
- {
- int i,j,k,rval,menuval;
- long timeval;
- char *response;
- char *basicdata[N_BASIC_FIELDS], *otherdata[100], *datum;
- Ptr_Rolo_List rlink;
-
- for (j = 0; j < 100; j++) otherdata[j] = 0;
- for (j = 0; j < N_BASIC_FIELDS; j++) basicdata[j] = 0;
- cathelpfile(libdir("addinfo"),0,1);
-
- /* 'k' and 'kludge' are are kludge to allow us to back up from entering */
- /* user defined fields to go an correct wrong basic field information. */
-
- k = 0;
-
- kludge :
-
- for (j = k; j < N_BASIC_FIELDS - 1; j++) {
-
- redo :
-
- rval = menu_match (
- &menuval,&response,
- Field_Names[j],
- 0,0,0,1,5,
- "\\",A_ABORT_ADD,
- "^",A_BACKUP,
- "!",A_FILL_IN_REST,
- "?",A_HELP,
- "",A_NO_DATA
- );
-
- switch (rval) {
-
- case MENU_NO_MATCH :
- basicdata[j] = copystr(response);
- if (j == 0 && strlen(basicdata[j]) == 0) {
- printf("Each entry must have a name!\n");
- goto redo;
- }
- break;
-
- case MENU_MATCH :
- switch (menuval) {
- case A_BACKUP :
- if (j == 0) return;
- j--;
- goto redo;
- break;
- case A_ABORT_ADD :
- return;
- break;
- case A_FILL_IN_REST :
- if (j == 0) {
- fprintf(stderr,"You must enter at least a name...\n");
- goto redo;
- }
- goto add_entry;
- break;
- case A_HELP :
- cathelpfile(libdir("addhelp"),"adding entries",1);
- any_char_to_continue();
- clear_the_screen();
- cathelpfile(libdir("addinfo"),0,0);
- for (i = 0; i < j; i++) {
- printf("%s%s\n",Field_Names[i],basicdata[i]);
- }
- goto redo;
- break;
- case A_NO_DATA :
- if (basicdata[j] != 0) basicdata[j][0] = '\0';
- break;
- default :
- fprintf(stderr,"Impossible rval from rolo_add menu_match\n");
- save_and_exit(-1);
- break;
- }
- break;
-
- case MENU_EOF :
- user_eof();
- break;
-
- case MENU_ERROR :
- case MENU_AMBIGUOUS :
- default :
- fprintf(stderr,"Impossible return from rolo_add menu_match\n");
- save_and_exit(-1);
- break;
-
- }
-
- }
-
- if (other_fields()) {
- for (j = 0; j < 100; j++) {
- redo_other :
- rval = menu_match (
- &menuval,&response,
- "Enter <name>: <data> (type RETURN to quit) : ",
- 0,0,0,0,5,
- "\\",O_ABORT,
- "?",O_HELP,
- "Help",O_HELP,
- "^",O_BACKUP,
- "",O_DONE_OTHERS
- );
- switch (rval) {
- case MENU_MATCH :
- switch (menuval) {
- case O_DONE_OTHERS :
- goto add_entry;
- break;
- case O_BACKUP :
- if (j == 0) {
- k = N_BASIC_FIELDS - 2;
- goto kludge;
- }
- else {
- j--;
- printf("Deleting %s\n",otherdata[j]);
- goto redo_other;
- }
- break;
- case O_ABORT :
- return;
- break;
- case O_HELP :
- cathelpfile(libdir("otherformathelp"),"user-item format",1);
- any_char_to_continue();
- goto redo_other;
- }
- break;
- case MENU_NO_MATCH :
- if (0 == index(response,':')) {
- printf("No field name provided -- separate with a ':'.\n");
- goto redo_other;
- }
- otherdata[j] = copystr(response);
- break;
- case MENU_EOF :
- user_eof();
- break;
- case MENU_AMBIGUOUS :
- case MENU_ERROR :
- default :
- fprintf(stderr,"Impossible rval from add_other menu_match\n");
- save_and_exit(-1);
- }
- }
- }
-
- add_entry :
-
- basicdata[N_BASIC_FIELDS - 1] = timestring();
-
- rlink = create_entry(basicdata,otherdata);
- clear_the_screen();
- display_entry(get_entry(rlink));
- if (add_the_entry()) {
- printf (
- "Adding entry for %s to rolodex\n",
- get_basic_rolo_field((int) R_NAME,get_entry(rlink))
- );
- rolo_insert(rlink,compare_links);
- changed = 1;
- sleep(2);
- }
- else {
- return;
- }
-
- }
-
-
- entry_action (rlink) Ptr_Rolo_List rlink;
-
- {
- static entry_menu_displayed = 0;
- int rval,menuval;
- char *response;
-
- if (!entry_menu_displayed) cathelpfile(libdir("entrymenu"),0,0);
- entry_menu_displayed = 1;
-
- redo :
-
- rval = menu_match (
- &menuval, &response,
- "Action (? for help) : ",
- 0,1,1,1,7,
- "\\",E_ABORT,
- "?",E_HELP,
- "",E_CONTINUE,
- "-",E_DELETE,
- "+",E_UPDATE,
- "<",E_PREV,
- "%",E_SCAN
- );
-
- if (rval != MENU_MATCH) {
- if (rval == MENU_EOF) user_eof();
- fprintf(stderr,"Impossible return from entry_action menu_match\n");
- save_and_exit(-1);
- }
-
- switch (menuval) {
- case E_ABORT :
- case E_CONTINUE :
- case E_PREV :
- break;
- case E_SCAN :
- rolo_peruse_mode(get_next_link(rlink));
- break;
- case E_UPDATE :
- rolo_update_mode(rlink);
- break;
- case E_DELETE :
- rolo_delete(rlink);
- printf("Entry deleted\n");
- sleep(1);
- changed = 1;
- break;
- case E_HELP :
- cathelpfile (
- libdir(in_search_mode ? "esearchhelp" : "escanhelp"),
- "entry actions",
- 1
- );
- any_char_to_continue();
- clear_the_screen();
- display_entry(get_entry(rlink));
- goto redo;
- break;
- default :
- fprintf(stderr,"Impossible menuval in entry_action\n");
- save_and_exit(-1);
- }
-
- return(menuval);
-
- }
-
-
- display_list_of_entries (rlist) Ptr_Rolo_List rlist;
-
- {
- Ptr_Rolo_List old;
-
- while (rlist != 0) {
-
- if (!get_matched(rlist)) goto next;
-
- loop :
-
- display_entry(get_entry(rlist));
-
- switch (entry_action(rlist)) {
- case E_CONTINUE :
- break;
- case E_ABORT :
- return;
- break;
- case E_PREV :
- old = rlist;
- find_prev_match :
- if (get_prev_link(rlist) == 0) {
- rlist = old;
- printf("No previous entry in scan list\n");
- sleep(2);
- }
- else {
- rlist = get_prev_link(rlist);
- if (!get_matched(rlist)) goto find_prev_match;
- }
- goto loop;
- break;
- default :
- printf("Displaying next entry in scan list...\n");
- sleep(1);
- break;
- }
-
- next :
-
- rlist = get_next_link(rlist);
-
- }
-
- printf("No further entries to scan...\n");
- sleep(2);
-
- }
-
-
- rolo_peruse_mode (first_rlink) Ptr_Rolo_List first_rlink;
-
- {
- int rval;
- Ptr_Rolo_List rlist = first_rlink;
- if (0 == Begin_Rlist) {
- fprintf(stderr,"No further entries in rolodex...\n");
- sleep(2);
- return;
- }
- while (rlist != 0) {
- set_matched(rlist);
- rlist = get_next_link(rlist);
- }
- display_list_of_entries(first_rlink);
- rlist = first_rlink;
- while (rlist != 0) {
- unset_matched(rlist);
- rlist = get_next_link(rlist);
- }
- }
- SHAR_EOF
- if test 8950 -ne "`wc -c < 'operations.c'`"
- then
- echo shar: error transmitting "'operations.c'" '(should have been 8950 characters)'
- fi
- fi
- echo shar: extracting "'options.c'" '(6785 characters)'
- if test -f 'options.c'
- then
- echo shar: will not over-write existing file "'options.c'"
- else
- cat << \SHAR_EOF > 'options.c'
- #include <sys/file.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <sgtty.h>
- #include <sys/time.h>
- #include <signal.h>
-
- #include "sys5.h"
-
- #ifdef TMC
- #include <ctools.h>
- #else
- #include "ctools.h"
- #endif
- #include "args.h"
- #include "menu.h"
- #include "mem.h"
-
- #include "rolofiles.h"
- #include "rolodefs.h"
- #include "datadef.h"
- #include "choices.h"
-
-
- print_short ()
-
- /* print the names and phone numbers of everyone in the rolodex. */
-
- {
-
- Ptr_Rolo_List rptr;
- Ptr_Rolo_Entry entry;
-
- rptr = Begin_Rlist;
- if (rptr == 0) {
- fprintf(stderr,"No entries to print out...\n");
- return;
- }
-
- fprintf (
- stdout,
- "\nNAME WORK PHONE HOME PHONE"
- );
- fprintf (
- stdout,
- "\n---- ---------- ----------\n\n\n"
- );
-
- while (rptr != 0) {
- entry = get_entry(rptr);
- fprintf (
- stdout,
- "%-25s %-25s %-25s\n",
- get_basic_rolo_field((int) R_NAME,entry),
- get_basic_rolo_field((int) R_WORK_PHONE,entry),
- get_basic_rolo_field((int) R_HOME_PHONE,entry)
- );
- rptr = get_next_link(rptr);
- }
-
- }
-
-
- person_match (person,entry) char *person; Ptr_Rolo_Entry entry;
-
- /* Match against a rolodex entry's Name and Company fields. */
- /* Thus if I say 'rolo CCA' I will find people who work at CCA. */
- /* This is good because sometimes you will forget a name but remember */
- /* the company the person works for. */
-
- {
- char *name, *company;
- int len;
- len = strlen(person);
- name = get_basic_rolo_field((int) R_NAME,entry);
- company = get_basic_rolo_field((int) R_COMPANY,entry);
- if (strncsearch(name,strlen(name),person,len)) return(1);
- if (strncsearch(company,strlen(company),person,len)) return(1);
- return(0);
- }
-
-
- int find_all_person_matches (person) char *person;
-
- {
- Ptr_Rolo_List rptr = Begin_Rlist;
- int count = 0;
- while (rptr != 0) {
- unset_matched(rptr);
- if (person_match(person,get_entry(rptr))) {
- set_matched(rptr);
- count++;
- }
- rptr = get_next_link(rptr);
- }
- return(count);
- }
-
-
- look_for_person (person) char *person;
-
- /* search against Name and Company over the rolodex. If a match is found */
- /* display the entry and give the user a choice of what to do next. */
-
- {
- Ptr_Rolo_List rptr;
- int found = 0,result,nmatches;
- static displayed_menu = 0;
- char *response;
-
- rptr = Begin_Rlist;
- while (rptr != 0) {
- if (person_match(person,get_entry(rptr))) {
- clear_the_screen();
- display_entry(get_entry(rptr));
- if (!found) {
- nmatches = find_all_person_matches(person);
- if (nmatches > 1) {
- printf (
- "There are %d other entries which match '%s'\n\n",
- nmatches - 1, person
- );
- }
- }
- found = 1;
- try_again :
- if (!displayed_menu) cathelpfile(libdir("poptionmenu"),0,0);
- displayed_menu = 1;
- menu_match (
- &result,
- &response,
- "Select option (? for help): ",
- 0,1,1,1,6,
- "Continue",P_CONTINUE,
- "",P_CONTINUE,
- "Next",P_NEXT_PERSON,
- "\\",P_ABORT,
- "Help",P_HELP,
- "?",P_HELP
- );
- switch (result) {
- case P_CONTINUE :
- break;
- case P_NEXT_PERSON :
- return;
- break;
- case P_ABORT :
- roloexit(0);
- break;
- case P_HELP :
- cathelpfile(libdir("poptionshelp"),"person search options",1);
- goto try_again;
- default :
- fprintf(stderr,"Impossible return from menu_match\n");
- exit(-1);
- }
- }
- rptr = get_next_link(rptr);
- }
- if (!found) {
- fprintf(stderr,"\nNo entry found for '%s'\n\n",person);
- sleep(2);
- }
- else {
- printf("No further matches for '%s'\n",person);
- sleep(2);
- }
- }
-
-
- print_people ()
-
- {
- int index;
- char *person;
- index = 1;
- while (T) {
- if (0 == (person = non_option_arg(index++))) break;
- look_for_person(person);
- }
- }
-
-
- interactive_rolo ()
-
- /* Top level of the iteractive rolodex. This code is just a big switch */
- /* which passes responsibility off to various routines in 'operations.c' */
- /* and 'update.c' */
-
- {
-
- int result,rval,field_index;
- char *response,*field_name,*search_string;
-
- fprintf(stdout,"\n\nTMC ROLODEX, Version %s\n\n\n",VERSION);
-
- while (1) {
-
- cathelpfile(libdir("mainmenu"),0,0);
- rval = menu_match (
- &result,
- &response,
- "Select option (? for help): ",
- 0,1,0,1,7,
- "+",M_ADD,
- "%",M_PERUSE,
- "\\",M_EXIT,
- "?",M_HELP,
- "*",M_SAVE,
- "$",M_SEARCH_BY_OTHER,
- "!",M_PRINT_TO_LASER_PRINTER
- );
-
- switch (rval) {
-
- case MENU_AMBIGUOUS :
- case MENU_ERROR :
- fprintf(stderr,"Impossible return 1 from main menu_match\n");
- exit(-1);
- break;
-
- case MENU_NO_MATCH :
- response = copystr(response);
- rolo_search_mode((int) R_NAME,Field_Names[(int) R_NAME],response);
- break;
-
- case MENU_MATCH :
-
- switch (result) {
- case M_ADD :
- rolo_add();
- break;
- case M_SEARCH_BY_OTHER :
- if ((-1 == select_field_to_search_by(&field_index,&field_name)) ||
- (0 == (search_string = select_search_string()))) {
- break;
- }
- rolo_search_mode(field_index,field_name,search_string);
- break;
- case M_PRINT_TO_LASER_PRINTER :
- fprintf(stderr,"Not implemented\n");
- sleep(1);
- break;
- case M_PERUSE :
- rolo_peruse_mode(Begin_Rlist);
- break;
- case M_EXIT :
- save_and_exit(0);
- break;
- case M_SAVE :
- if (changed) {
- save_to_disk();
- sleep(1);
- }
- else {
- printf("No changes to be saved...\n");
- sleep(2);
- }
- break;
- case M_HELP :
- cathelpfile(libdir("moptionhelp"),"top level menu",1);
- any_char_to_continue();
- break;
- default :
- fprintf(stderr,"Impossible result from menu_match...\n");
- save_and_exit(-1);
- }
- break;
-
- case MENU_EOF :
- user_eof();
- break;
-
- default :
- fprintf(stderr,"Impossible return 2 from menu_match\n");
- save_and_exit(-1);
-
- }
-
- clear_the_screen();
-
- }
-
- }
- SHAR_EOF
- if test 6785 -ne "`wc -c < 'options.c'`"
- then
- echo shar: error transmitting "'options.c'" '(should have been 6785 characters)'
- fi
- fi
- echo shar: extracting "'rlist.c'" '(2445 characters)'
- if test -f 'rlist.c'
- then
- echo shar: will not over-write existing file "'rlist.c'"
- else
- cat << \SHAR_EOF > 'rlist.c'
- #include "datadef.h"
-
-
- int rlength (rlist) Ptr_Rolo_List rlist;
- {
- return((rlist == 0) ? 0 : 1 + rlength(get_next_link(rlist)));
- }
-
-
- Ptr_Rolo_List new_link_with_entry ()
- {
- Ptr_Rolo_List newlink;
- Ptr_Rolo_Entry newentry;
- newlink = (Ptr_Rolo_List) rolo_emalloc(sizeof(Rolo_List));
- unset_matched(newlink);
- newentry = (Ptr_Rolo_Entry) rolo_emalloc(sizeof(Rolo_Entry));
- set_n_others(newentry,0);
- newentry -> other_fields = 0;
- set_entry(newlink,newentry);
- return(newlink);
- }
-
-
- rolo_insert (link,compare) Ptr_Rolo_List link; int (*compare)();
-
- {
- Ptr_Rolo_List rptr;
-
- if (Begin_Rlist == 0) {
- Begin_Rlist = link;
- End_Rlist = link;
- set_prev_link(link,0);
- set_next_link(link,0);
- return;
- }
-
- /* find the element it goes before, alphabetically, and insert it */
-
- rptr = Begin_Rlist;
- while (rptr != 0) {
- if (1 == (*compare)(rptr,link)) {
- set_prev_link(link,get_prev_link(rptr));
- set_next_link(link,rptr);
- if (get_prev_link(rptr) != 0)
- set_next_link(get_prev_link(rptr),link);
- else
- Begin_Rlist = link;
- set_prev_link(rptr,link);
- return;
- }
- rptr = get_next_link(rptr);
- }
-
- /* it goes at the end */
-
- set_next_link(End_Rlist,link);
- set_prev_link(link,End_Rlist);
- set_next_link(link,0);
- End_Rlist = link;
- return;
-
- }
-
-
- rolo_delete (link) Ptr_Rolo_List link;
-
- {
- if (get_next_link(link) == 0 && get_prev_link(link) == 0) {
- Begin_Rlist = 0;
- End_Rlist = 0;
- return;
- }
-
- if (get_prev_link(link) == 0) {
- Begin_Rlist = get_next_link(link);
- set_prev_link(Begin_Rlist,0);
- return;
- }
-
- if (get_next_link(link) == 0) {
- End_Rlist = get_prev_link(link);
- set_next_link(End_Rlist,0);
- return;
- }
-
- set_next_link(get_prev_link(link),get_next_link(link));
- set_prev_link(get_next_link(link),get_prev_link(link));
- return;
-
- }
-
-
- compare_links (l1,l2) Ptr_Rolo_List l1,l2;
-
- {
- Ptr_Rolo_Entry e1,e2;
- char *n1,*n2;
- e1 = get_entry(l1);
- e2 = get_entry(l2);
- n1 = get_basic_rolo_field((int) R_NAME,e1);
- n2 = get_basic_rolo_field((int) R_NAME,e2);
- return(nocase_compare(n1,strlen(n1),n2,strlen(n2)));
- }
-
-
- rolo_reorder ()
- {
- Ptr_Rolo_List rptr,oldlink;
- rptr = Begin_Rlist;
- Begin_Rlist = 0;
- while (rptr != 0) {
- oldlink = get_next_link(rptr);
- rolo_insert(rptr,compare_links);
- rptr = oldlink;
- }
- }
-
-
- SHAR_EOF
- if test 2445 -ne "`wc -c < 'rlist.c'`"
- then
- echo shar: error transmitting "'rlist.c'" '(should have been 2445 characters)'
- fi
- fi
- echo shar: extracting "'rolo.c'" '(8738 characters)'
- if test -f 'rolo.c'
- then
- echo shar: will not over-write existing file "'rolo.c'"
- else
- cat << \SHAR_EOF > 'rolo.c'
- #include <sys/file.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <sgtty.h>
- #include <signal.h>
- #include <curses.h>
- #include <pwd.h>
-
- #include "sys5.h"
-
- #ifdef TMC
- #include <ctools.h>
- #else
- #include "ctools.h"
- #endif
- #include "args.h"
- #include "menu.h"
- #include "mem.h"
-
- #include "rolofiles.h"
- #include "rolodefs.h"
- #include "datadef.h"
-
-
- static char rolodir[DIRPATHLEN]; /* directory where rolo data is */
- static char filebuf[DIRPATHLEN]; /* stores result of homedir() */
-
- int changed = 0;
- int reorder_file = 0;
- int rololocked = 0;
- int in_search_mode = 0;
-
-
- char *rolo_emalloc (size) int size;
-
- /* error handling memory allocator */
-
- {
- char *rval;
- if (0 == (rval = malloc(size))) {
- fprintf(stderr,"Fatal error: out of memory\n");
- save_and_exit(-1);
- }
- return(rval);
- }
-
-
- char *copystr (s) char *s;
-
- /* memory allocating string copy routine */
-
-
- {
- char *copy;
- if (s == 0) return(0);
- copy = rolo_emalloc(strlen(s) + 1);
- strcpy(copy,s);
- return(copy);
- }
-
-
- char *timestring ()
-
- /* returns a string timestamp */
-
- {
- char *s;
- long timeval;
- time(&timeval);
- s = ctime(&timeval);
- s[strlen(s) - 1] = '\0';
- return(copystr(s));
- }
-
-
- user_interrupt ()
-
- /* if the user hits C-C (we assume he does it deliberately) */
-
- {
- unlink(homedir(ROLOLOCK));
- fprintf(stderr,"\nAborting rolodex, no changes since last save recorded\n");
- exit(-1);
- }
-
-
- user_eof ()
-
- /* if the user hits C-D */
-
- {
- unlink(homedir(ROLOLOCK));
- fprintf(stderr,"\nUnexpected EOF on terminal. Saving rolodex and exiting\n");
- save_and_exit(-1);
- }
-
-
- roloexit (rval) int rval;
- {
- if (rololocked) unlink(homedir(ROLOLOCK));
- exit(rval);
- }
-
-
- save_to_disk ()
-
- /* move the old rolodex to a backup, and write out the new rolodex and */
- /* a copy of the new rolodex (just for safety) */
-
- {
- FILE *tempfp,*copyfp;
- char d1[DIRPATHLEN], d2[DIRPATHLEN];
- int r;
-
- tempfp = fopen(homedir(ROLOTEMP),"w");
- copyfp = fopen(homedir(ROLOCOPY),"w");
- if (tempfp == NULL || copyfp == NULL) {
- fprintf(stderr,"Unable to write rolodex...\n");
- fprintf(stderr,"Any changes made have not been recorded\n");
- roloexit(-1);
- }
- write_rolo(tempfp,copyfp);
- fclose(tempfp);
- fclose(copyfp);
- if (rename(strcpy(d1,homedir(ROLODATA)),strcpy(d2,homedir(ROLOBAK))) ||
- rename(strcpy(d1,homedir(ROLOTEMP)),strcpy(d2,homedir(ROLODATA)))) {
- fprintf(stderr,"Rename failed. Revised rolodex is in %s\n",ROLOCOPY);
- roloexit(-1);
- }
- printf("Rolodex saved\n");
- sleep(1);
- changed = 0;
- }
-
-
- save_and_exit (rval) int rval;
- {
- if (changed) save_to_disk();
- roloexit(rval);
- }
-
-
- extern struct passwd *getpwnam();
-
- char *home_directory (name) char *name;
- {
- struct passwd *pwentry;
- if (0 == (pwentry = getpwnam(name))) return("");
- return(pwentry -> pw_dir);
- }
-
-
- char *homedir (filename) char *filename;
-
- /* e.g., given "rolodex.dat", create "/u/massar/rolodex.dat" */
- /* rolodir generally the user's home directory but could be someone else's */
- /* home directory if the -u option is used. */
-
- {
- nbuffconcat(filebuf,3,rolodir,"/",filename);
- return(filebuf);
- }
-
-
- char *libdir (filename) char *filename;
-
- /* return a full pathname into the rolodex library directory */
- /* the string must be copied if it is to be saved! */
-
- {
- nbuffconcat(filebuf,3,ROLOLIB,"/",filename);
- return(filebuf);
- }
-
-
- rolo_only_to_read ()
- {
- return(option_present(SUMMARYFLAG) || n_non_option_args() > 0);
- }
-
-
- locked_action ()
- {
- if (option_present(OTHERUSERFLAG)) {
- fprintf(stderr,"Someone else is modifying that rolodex, sorry\n");
- exit(-1);
- }
- else {
- cathelpfile(libdir("lockinfo"),"locked rolodex",0);
- exit(-1);
- }
- }
-
-
- main (argc,argv) int argc; char *argv[];
-
- {
- int fd,in_use,read_only,rolofd;
- Bool not_own_rolodex;
- char *user;
- FILE *tempfp;
-
- clearinit();
- clear_the_screen();
-
- /* parse the options and arguments, if any */
-
- switch (get_args(argc,argv,T,T)) {
- case ARG_ERROR :
- roloexit(-1);
- case NO_ARGS :
- break;
- case ARGS_PRESENT :
- if (ALL_LEGAL != legal_options(LEGAL_OPTIONS)) {
- fprintf(stderr,"illegal option\nusage: %s\n",USAGE);
- roloexit(-1);
- }
- }
-
- /* find the directory in which the rolodex file we want to use is */
-
- not_own_rolodex = option_present(OTHERUSERFLAG);
- if (not_own_rolodex) {
- if (NIL == (user = option_arg(OTHERUSERFLAG,1)) ||
- n_option_args(OTHERUSERFLAG) != 1) {
- fprintf(stderr,"Illegal syntax using -u option\nusage: %s\n",USAGE);
- roloexit(-1);
- }
- }
- else {
- if (0 == (user = getenv("HOME"))) {
- fprintf(stderr,"Cant find your home directory, no HOME\n");
- roloexit(-1);
- }
- }
-
- if (not_own_rolodex) {
- strcpy(rolodir,home_directory(user));
- if (*rolodir == '\0') {
- fprintf(stderr,"No user %s is known to the system\n",user);
- roloexit(-1);
- }
- }
- else strcpy(rolodir,user);
-
- /* is the rolodex readable? */
-
- if (0 != access(homedir(ROLODATA),R_OK)) {
-
- /* No. if it exists and we cant read it, that's an error */
-
- if (0 == access(homedir(ROLODATA),F_OK)) {
- fprintf(stderr,"Cant access rolodex data file to read\n");
- roloexit(-1);
- }
-
- /* if it doesn't exist, should we create one? */
-
- if (option_present(OTHERUSERFLAG)) {
- fprintf(stderr,"No rolodex file belonging to %s found\n",user);
- roloexit(-1);
- }
-
- /* try to create it */
-
- if (-1 == (fd = creat(homedir(ROLODATA),0644))) {
- fprintf(stderr,"couldnt create rolodex in your home directory\n");
- roloexit(-1);
- }
-
- else {
- close(fd);
- fprintf(stderr,"Creating empty rolodex...\n");
- }
-
- }
-
- /* see if someone else is using it */
-
- in_use = (0 == access(homedir(ROLOLOCK),F_OK));
-
- /* are we going to access the rolodex only for reading? */
-
- if (!(read_only = rolo_only_to_read())) {
-
- /* No. Make sure no one else has it locked. */
-
- if (in_use) {
- locked_action();
- }
-
- /* create a lock file. Catch interrupts so that we can remove */
- /* the lock file if the user decides to abort */
-
- if (!option_present(NOLOCKFLAG)) {
- if ((fd = open(homedir(ROLOLOCK),O_EXCL|O_CREAT,00200|00400)) < 0) {
- fprintf(stderr,"unable to create lock file...\n");
- exit(1);
- }
- rololocked = 1;
- close(fd);
- signal(SIGINT,user_interrupt);
- }
-
- /* open a temporary file for writing changes to make sure we can */
- /* write into the directory */
-
- /* when the rolodex is saved, the old rolodex is moved to */
- /* a '~' file, the temporary is made to be the new rolodex, */
- /* and a copy of the new rolodex is made */
-
- if (NULL == (tempfp = fopen(homedir(ROLOTEMP),"w"))) {
- fprintf(stderr,"Can't open temporary file to write to\n");
- roloexit(-1);
- }
- fclose(tempfp);
-
- }
-
- allocate_memory_chunk(CHUNKSIZE);
-
- if (NULL == (rolofd = open(homedir(ROLODATA),O_RDONLY))) {
- fprintf(stderr,"Can't open rolodex data file to read\n");
- roloexit(-1);
- }
-
- /* read in the rolodex from disk */
- /* It should never be out of order since it is written to disk ordered */
- /* but just in case... */
-
- if (!read_only) printf("Reading in rolodex from %s\n",homedir(ROLODATA));
- read_rolodex(rolofd);
- close(rolofd);
- if (!read_only) printf("%d entries listed\n",rlength(Begin_Rlist));
- if (reorder_file && !read_only) {
- fprintf(stderr,"Reordering rolodex...\n");
- rolo_reorder();
- fprintf(stderr,"Saving reordered rolodex to disk...\n");
- save_to_disk();
- }
-
- /* the following routines live in 'options.c' */
-
- /* -s option. Prints a short listing of people and phone numbers to */
- /* standard output */
-
- if (option_present(SUMMARYFLAG)) {
- print_short();
- exit(0);
- }
-
- /* rolo <name1> <name2> ... */
- /* print out info about people whose names contain any of the arguments */
-
- if (n_non_option_args() > 0) {
- print_people();
- exit(0);
- }
-
- /* regular rolodex program */
-
- interactive_rolo();
- exit(0);
-
- }
- SHAR_EOF
- if test 8738 -ne "`wc -c < 'rolo.c'`"
- then
- echo shar: error transmitting "'rolo.c'" '(should have been 8738 characters)'
- fi
- fi
- echo shar: extracting "'rolodefs.h'" '(262 characters)'
- if test -f 'rolodefs.h'
- then
- echo shar: will not over-write existing file "'rolodefs.h'"
- else
- cat << \SHAR_EOF > 'rolodefs.h'
- #define VERSION "2.0"
-
- #define CHUNKSIZE 100000 /* storage size for holding data file */
-
- #define NOLOCKFLAG 'l'
- #define SUMMARYFLAG 's'
- #define OTHERUSERFLAG 'u'
-
- #define LEGAL_OPTIONS "lsu"
- #define USAGE "rolo [ person1 person2 ...] [ -l -s -u user ] "
- SHAR_EOF
- if test 262 -ne "`wc -c < 'rolodefs.h'`"
- then
- echo shar: error transmitting "'rolodefs.h'" '(should have been 262 characters)'
- fi
- fi
- echo shar: extracting "'rolofiles.h'" '(280 characters)'
- if test -f 'rolofiles.h'
- then
- echo shar: will not over-write existing file "'rolofiles.h'"
- else
- cat << \SHAR_EOF > 'rolofiles.h'
- #define ROLOBAK ".rolodex~"
- #define ROLODATA ".rolodex.dat"
- #define ROLOPRINT "roloprint.text"
- #define ROLOLOCK ".rolodexdata.lock"
- #define ROLOTEMP ".rolotemp"
- #define ROLOCOPY ".rolocopy"
-
- /* This is now defined in the Makefile */
-
- /* #define ROLOLIB "/usr/local/lib/rolo" */
- SHAR_EOF
- if test 280 -ne "`wc -c < 'rolofiles.h'`"
- then
- echo shar: error transmitting "'rolofiles.h'" '(should have been 280 characters)'
- fi
- fi
- echo shar: extracting "'search.c'" '(9108 characters)'
- if test -f 'search.c'
- then
- echo shar: will not over-write existing file "'search.c'"
- else
- cat << \SHAR_EOF > 'search.c'
- #include <stdio.h>
- #include <ctype.h>
-
- #include "sys5.h"
-
- #ifdef TMC
- #include <ctools.h>
- #else
- #include "ctools.h"
- #endif
- #include "args.h"
- #include "menu.h"
- #include "mem.h"
-
- #include "rolofiles.h"
- #include "rolodefs.h"
- #include "datadef.h"
- #include "choices.h"
-
-
- char *select_search_string ()
-
- /* returns 0 if user wants to quit, otherwise returns a user-provided string */
-
- {
- int rval;
- char *response;
- rval = rolo_menu_data_help_or_abort (
- "Enter string to search for: ",
- "searchstringhelp",
- "string to search for",
- &response
- );
- switch (rval) {
- case MENU_ABORT :
- return(0);
- break;
- case MENU_DATA :
- return(copystr(response));
- break;
- }
- }
-
-
- select_field_to_search_by (ptr_index,ptr_name) int *ptr_index; char **ptr_name;
-
- /* returns -1 if the user wishes to abort, otherwise returns 0. */
- /* if the user wishes to search by a user-defined field, *ptr_index is OTHER */
- /* and *ptr_name is the user-provided name of the field. */
-
- {
- char *response;
- int nchoices = N_BASIC_FIELDS;
- int field_index,rval;
-
- redo :
-
- /* list out each basic field that the user can search by. The user is */
- /* also given an option to search by a user-provided field. At the */
- /* moment you cannot search by 'Date Updated' */
-
- display_field_names();
-
- reask :
-
- rval = rolo_menu_number_help_or_abort (
- "Number of item to search by? ",
- 1,nchoices,&field_index
- );
-
- switch (rval) {
-
- case MENU_ABORT :
- return(-1);
- break;
-
- case MENU_HELP :
- cathelpfile(libdir("fieldsearchhelp"),"entering search field",1);
- any_char_to_continue();
- goto redo;
- break;
-
- case MENU_DATA :
-
- if (field_index != nchoices) {
- *ptr_index = field_index - 1;
- *ptr_name = copystr(Field_Names[*ptr_index]);
- return(0);
- }
-
- /* the user wants to search by a user-specified field */
-
- else {
-
- reask2 :
-
- rval = rolo_menu_data_help_or_abort (
- "Name of user-defined field? ",
- "userfieldhelp",
- "name of user field to search by",
- &response
- );
- switch (rval) {
- case MENU_ABORT :
- return(-1);
- break;
- case MENU_DATA :
- *ptr_index = OTHER;
- *ptr_name = copystr(response);
- return(0);
- break;
- }
- }
- break;
- }
-
- }
-
-
- match_by_name_or_company (search_string,sslen) char *search_string; int sslen;
-
- {
- char *name,*company;
- Ptr_Rolo_Entry entry;
- Ptr_Rolo_List rlist;
- int count = 0;
-
- rlist = Begin_Rlist;
- while (rlist != 0) {
- entry = get_entry(rlist);
- name = get_basic_rolo_field((int) R_NAME,entry);
- company = get_basic_rolo_field((int) R_COMPANY,entry);
- if (strncsearch(name,strlen(name),search_string,sslen) ||
- strncsearch(company,strlen(company),search_string,sslen)) {
- set_matched(rlist);
- count++;
- }
- }
- return(count);
-
- }
-
-
- match_link (rlink,field_index,field_name,fnlen,search_string,sslen)
-
- /* if a match is present, sets the 'matched' field in the link, and */
- /* returns 1, otherwise returns 0. */
-
- Ptr_Rolo_List rlink;
- int field_index;
- char *field_name;
- int fnlen;
- char *search_string;
- int sslen;
-
- {
- Ptr_Rolo_Entry entry;
- char *field;
- char name[100];
- int j;
-
- entry = get_entry(rlink);
-
- if (field_index == OTHER) {
- for (j = 0; j < get_n_others(entry); j++) {
- field = get_other_field(j,entry);
- while (*field != ':') *field++;
- *field = '\0';
- remove_excess_blanks(name,get_other_field(j,entry));
- *field++ = ':';
- if (0 != nocase_compare(name,strlen(name),field_name,fnlen)) {
- continue;
- }
- if (strncsearch(field,strlen(field),search_string,sslen)) {
- set_matched(rlink);
- return(1);
- }
- }
- return(0);
- }
- else {
- field = get_basic_rolo_field(field_index,entry);
- if (strncsearch(field,strlen(field),search_string,sslen)) {
- set_matched(rlink);
- return(1);
- }
- return(0);
- }
-
- }
-
-
- find_all_matches (field_index,field_name,search_string,ptr_first_match)
-
- /* mark every entry in the rolodex which matches against the search_string */
- /* If the search_string is a substring of the data in the given field then */
- /* that is a match. Return the number of matches. If there are any */
- /* matches *ptr_first_match will contain the first matching link. */
-
- int field_index;
- char *field_name, *search_string;
- Ptr_Rolo_List *ptr_first_match;
-
- {
- char buffer[100];
- int fnlen,sslen;
- int count = 0;
- Ptr_Rolo_List rlist = Begin_Rlist;
-
- remove_excess_blanks(buffer,field_name);
- fnlen = strlen(buffer);
- sslen = strlen(search_string);
-
- while (rlist != 0) {
- unset_matched(rlist);
- if (match_link(rlist,field_index,buffer,fnlen,search_string,sslen)) {
- if (count++ == 0) *ptr_first_match = rlist;
- }
- rlist = get_next_link(rlist);
- }
-
- return(count);
-
- }
-
-
- rolo_search_mode (field_index,field_name,search_string)
-
- int field_index;
- char *field_name;
- char *search_string;
-
- {
- int rval,n,j,menuval,ival;
- char *response;
- Ptr_Rolo_List first_match,rmatch,rlist;
-
- /* mark every entry in the rolodex that satisfies the search criteria */
- /* and return the number of items so marked. */
-
- in_search_mode = 1;
- n = find_all_matches(field_index,field_name,search_string,&first_match);
-
- if (n == 0) {
- printf (
- "No match found for search string '%s' for field '%s'\n",
- search_string,
- field_name
- );
- sleep(2);
- goto rtn;
- }
-
- /* if the match is unique, just display the entry. */
-
- else if (n == 1) {
- display_entry(get_entry(first_match));
- switch (entry_action(first_match)) {
- case E_CONTINUE :
- printf("No further matches...\n");
- sleep(2);
- break;
- default :
- break;
- }
- goto rtn;
- }
-
- /* if there are too many matches to itemize them on a single small */
- /* screen, tell the user that there are lots of matches and suggest */
- /* he specify a better search string, but give him the option of */
- /* iterating through every match. */
-
- else if (n > MAXMATCHES) {
- clear_the_screen();
- printf("There are %d entries that match '%s' !\n",n,search_string);
- printf("Type 'v' to view them one by one,\n");
- printf("or '\\' to abort and enter a more specific search string: ");
- rval = rolo_menu_data_help_or_abort (
- "","manymatchhelp","many matching entries",&response
- );
- if (rval == MENU_ABORT) goto rtn;
- display_list_of_entries(Begin_Rlist);
- goto rtn;
- }
-
- /* there are a small number of matching entries. List the name of each */
- /* matching entry and let the user select which one he wants to view, */
- /* or whether he wants to iterate through each matching entry. */
-
- else {
- relist :
- summarize_entry_list(Begin_Rlist,search_string);
- cathelpfile(libdir("pickentrymenu"),0,0);
- rval = menu_match (
- &menuval,&response,
- ": ",
- 0,1,0,1,4,
- "\\",S_ABORT,
- "?",S_HELP,
- "Help",S_HELP,
- "",S_SCAN_ONE_BY_ONE
- );
- switch (rval) {
- case MENU_MATCH :
- switch (menuval) {
- case S_HELP :
- cathelpfile(libdir("pickentryhelp"),"selecting entry to view",1);
- any_char_to_continue();
- goto relist;
- break;
- case S_ABORT :
- goto rtn;
- break;
- case S_SCAN_ONE_BY_ONE :
- display_list_of_entries(Begin_Rlist);
- goto rtn;
- break;
- }
- break;
-
- /* make sure the user entered a valid integer, ival */
- /* if so, find the ivalth entry marked as matched in the rolodex */
- /* and display it. */
-
- case MENU_NO_MATCH :
- ival = str_to_pos_int(response,1,n);
- if (ival < 0) {
- printf("Not a valid number... Please try again\n");
- sleep(2);
- goto relist;
- }
- rlist = Begin_Rlist;
- for (j = 0; j < ival; j++) {
- while (rlist != 0) {
- if (get_matched(rmatch = rlist)) break;
- rlist = get_next_link(rlist);
- }
- if (rlist != 0) rlist = get_next_link(rlist);
- }
- display_entry(get_entry(rmatch));
- switch (entry_action(rmatch)) {
- case E_CONTINUE :
- case E_PREV :
- goto relist;
- break;
- default :
- goto rtn;
- break;
- }
- break;
- }
- }
-
- rtn :
- in_search_mode = 0;
-
- }
- SHAR_EOF
- if test 9108 -ne "`wc -c < 'search.c'`"
- then
- echo shar: error transmitting "'search.c'" '(should have been 9108 characters)'
- fi
- fi
- echo shar: extracting "'update.c'" '(6022 characters)'
- if test -f 'update.c'
- then
- echo shar: will not over-write existing file "'update.c'"
- else
- cat << \SHAR_EOF > 'update.c'
- #include <stdio.h>
- #include <ctype.h>
-
- #include "sys5.h"
-
- #ifdef TMC
- #include <ctools.h>
- #else
- #include "ctools.h"
- #endif
- #include "args.h"
- #include "menu.h"
- #include "mem.h"
-
- #include "rolofiles.h"
- #include "rolodefs.h"
- #include "datadef.h"
- #include "choices.h"
-
-
- char *get_new_value ()
- {
- char buffer[200];
- int rval;
- switch (rval = getline(stdin,buffer,199)) {
- case AT_EOF :
- user_eof();
- break;
- case TOO_MANY_CHARS :
- fprintf(stderr,"Line too long, truncated...\n");
- sleep(1);
- break;
- default :
- if ('\\' == *buffer && rval == 1) return(0);
- break;
- }
- return(copystr(buffer));
- }
-
-
- Ptr_Rolo_Entry copy_entry (entry) Ptr_Rolo_Entry entry;
- {
- Ptr_Rolo_Entry new_entry;
- int j,n;
- char **otherfields;
-
- new_entry = (Ptr_Rolo_Entry) rolo_emalloc(sizeof(Rolo_Entry));
-
- /* copy the basic fields, but get a new timestamp */
-
- for (j = 0; j < N_BASIC_FIELDS - 1; j++) {
- set_basic_rolo_field(j,new_entry,copystr(get_basic_rolo_field(j,entry)));
- }
- set_basic_rolo_field(N_BASIC_FIELDS - 1,new_entry,timestring());
-
- /* copy the user-defined fields, if necessary */
-
- set_n_others(new_entry,n = get_n_others(entry));
- if (n > 0) {
- otherfields = (char **) rolo_emalloc(n * sizeof(char *));
- new_entry -> other_fields = otherfields;
- for (j = 0; j < n; j++) {
- set_other_field(j,new_entry,copystr(get_other_field(j,entry)));
- }
- }
- else new_entry -> other_fields = 0;
-
- return(new_entry);
-
- }
-
-
- rolo_update_mode (rlink) Ptr_Rolo_List rlink;
-
- /* Update the fields of an entry. The user is not allowed to modify the */
- /* timestamp field. */
-
- {
- int rval,menuval,findex,updated,newlen,n,nfields,j,name_changed;
- char *response,*s,*newfield,*newval,*other, **others;
- Ptr_Rolo_Entry entry,old_entry;
-
- cancel_update :
-
- entry = copy_entry(old_entry = get_entry(rlink));
-
- updated = 0;
- name_changed = 0;
-
- redisplay :
-
- display_entry_for_update(updated ? entry : old_entry);
- nfields = (N_BASIC_FIELDS - 1) + get_n_others(entry);
-
- reask :
-
- cathelpfile(libdir("updatemenu"),0,0);
-
- rval = menu_match (
- &menuval,&response,
- ": ",
- 0,1,0,1,4,
- "\\",U_ABORT,
- "?",U_HELP,
- "Help",U_HELP,
- "",U_END_UPDATE
- );
-
- switch (rval) {
-
- case MENU_MATCH :
-
- switch (menuval) {
-
- case U_HELP :
- cathelpfile(libdir("updatehelp"),"updating",1);
- any_char_to_continue();
- clear_the_screen();
- goto redisplay;
-
- case U_ABORT :
- if (updated) {
- printf("Previous updates to fields in this entry ignored\n");
- }
- return;
- break;
-
- case U_END_UPDATE :
- if (!updated) goto reask;
- display_entry(entry);
- if (MENU_YES == rolo_menu_yes_no (
- "Confirm Update? ",DEFAULT_YES,1,
- "confirmhelp","confirming update"
- )) {
- printf("Update confirmed\n");
- sleep(1);
- set_entry(rlink,entry);
- if (name_changed) {
- rolo_delete(rlink);
- rolo_insert(rlink,compare_links);
- }
- changed = 1;
- return;
- }
- else {
- printf("Updates ignored...\n");
- sleep(1);
- updated = 0;
- goto cancel_update;
- }
- break;
-
- }
- break;
-
- case MENU_NO_MATCH :
-
- /* check that the response is an integer within range */
-
- findex = str_to_pos_int(response,1,nfields+1);
- if (findex < 0) {
- printf("Not a valid number...Please try again\n");
- goto reask;
- }
- findex--;
-
- /* we can either be updating a standard field or a user-defined field */
- /* or adding a new field */
-
- if (findex < N_BASIC_FIELDS - 1) {
- name_changed = (findex == 0);
- printf("Updating '%s'\n",Field_Names[findex]);
- printf("Old value: %s\n",get_basic_rolo_field(findex,entry));
- printf("New value: ");
- if (0 == (newval = copystr(get_new_value()))) break;
- set_basic_rolo_field(findex,entry,newval);
- updated = 1;
- }
- else if (findex != nfields) {
- findex -= N_BASIC_FIELDS - 1;
- printf("Updating \'");
- s = other = get_other_field(findex,entry);
- while (*s != ':') putc(*s++,stdout);
- printf("\' field\n");
- printf("Old value: %s\n",++s);
- printf("New value: ");
- if (0 == (newval = copystr(get_new_value()))) break;
- if (strlen(newval) == 0) {
- for (j = findex; j < get_n_others(entry); j++) {
- set_other_field(j,entry,get_other_field(j+1,entry));
- }
- set_n_others(entry,get_n_others(entry) - 1);
- }
- else {
- *s = '\0';
- newlen = strlen(other) + strlen(newval) + 2;
- newfield = rolo_emalloc(newlen);
- nbuffconcat(newfield,3,other," ",newval);
- set_other_field(findex,entry,newfield);
- }
- updated = 1;
- }
- else {
- loop:
- printf("New field (<name>: <value>): ");
- if (0 == (newfield = copystr(get_new_value()))) break;
- if (0 == index(newfield,':')) {
- fprintf(stderr,"No field name. Use a ':'...\n");
- goto loop;
- }
- n = get_n_others(entry);
- set_n_others(entry,n + 1);
- others = (char **) rolo_emalloc((n + 1) * sizeof(char *));
- for (j = 0; j < n; j++) others[j] = get_other_field(j,entry);
- others[n] = newfield;
- entry -> other_fields = others;
- updated = 1;
- }
- break;
-
- case MENU_EOF :
- user_eof();
- break;
-
- default :
- fprintf(stderr,"Impossible return from update menu_match\n");
- save_and_exit(-1);
- break;
-
- }
-
- goto redisplay;
-
- }
- SHAR_EOF
- if test 6022 -ne "`wc -c < 'update.c'`"
- then
- echo shar: error transmitting "'update.c'" '(should have been 6022 characters)'
- fi
- fi
- exit 0
- # End of shell archive
-